home *** CD-ROM | disk | FTP | other *** search
-
-
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
- /* */
- /* This file contains the code for implementing the cApplication AE object. */
- /* */
- /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
-
- #include "AEPackObject.h"
- #include <Scrap.h>
- #include "AEObjects.h"
- #include "AERegistry.h"
-
- #include "ScriptScrap.h"
- #include "Prototypes.h"
-
-
- /* Property from object accessors */
- pascal OSErr PropertyFromNullAccessor ( DescType desiredClass,
- const AEDesc *container, DescType containerClass, DescType keyForm,
- const AEDesc *keyData, AEDesc *returnedToken, long refCon )
- {
- OSErr err = noErr;
- ourToken tokenBody;
- DescType requestedProperty;
-
- /* In our model, all a property accessor does is copy the container */
- /* token and change the token to represent a property. The token */
- /* handlers will do the actual reading and writing of the data in */
- /* the token. */
- if ((keyForm != formPropertyID) || (keyData->descriptorType != typeType))
- return errAECantSupplyType;
-
- if (container->descriptorType != 'null')
- return errAETypeError;
-
- requestedProperty = **(DescType**)keyData->dataHandle;
-
- /* Initialize the body of the token */
- tokenBody.dispatchClass = cApplication; /* The parent of this object… */
- tokenBody.flags = kPropToken; /* We're returning a property code */
- tokenBody.docWindow = NULL; /* Not used */
- tokenBody.fRefNum = 0; /* Not used */
-
- /* Check to see if this is a legal property code for this object class */
- switch (requestedProperty) {
- case pBestType:
- case pClass:
- case pDefaultType:
- case pInsertionLoc:
- case pIsFrontProcess:
- case pName:
- case pUserSelection:
- case pVersion:
- tokenBody.propertyCode = requestedProperty;
- break;
-
- case pClipboard:
- tokenBody.propertyCode = requestedProperty;
- tokenBody.flags = kPropToken;
- break;
-
- default:
- return errAECantSupplyType;
- }
-
- /* Pass this token back to the OSL */
- return AECreateDesc(desiredClass, (Ptr)&tokenBody, sizeof(tokenBody), returnedToken);
- } /* PropertyFromNullAccessor */
-
-
- /* Token resolvers -- read, write */
-
- OSErr App_ReadTokenData(const AEDesc *theToken, AEDesc *tokenContents)
- {
- long versionCode = 0x0002;
- DescType scratchType;
- DescType propCode;
- OSErr err = noErr;
- AEDesc keyData,
- nullDesc = {'null', NULL};
- AEDesc scratchDesc;
- long documentNumber;
-
- if (tokenFlags(*theToken) & kPropToken) {
- /* Return any readable properties of the appointment */
- propCode = tokenPropCode(*theToken);
- switch (propCode) {
- case pBestType:
- case pClass:
- scratchType = cApplication;
- return AECreateDesc(typeType, (Ptr)&scratchType, sizeof(scratchType), tokenContents);
- break;
-
- case pDefaultType:
- scratchType = cApplication;
- return AECreateDesc(typeType, (Ptr)&scratchType, sizeof(scratchType), tokenContents);
- break;
-
- case pInsertionLoc:
- if (FrontWindow() != NULL) {
- /* return the object specifier "window 1" */
- documentNumber = 1;
- (void)AECreateDesc(typeIndexDescriptor, (Ptr)&documentNumber, sizeof(documentNumber), &keyData);
- (void)CreateObjSpecifier(cDocument, &nullDesc, formAbsolutePosition, &keyData, true, tokenContents);
- AEDisposeDesc(&keyData);
- } else
- *tokenContents = nullDesc;
- break;
-
- case pIsFrontProcess:
- return AECreateDesc(cBoolean, (Ptr)&gInFront, sizeof(gInFront), tokenContents);
- break;
-
- case pName: {
- Str255 appName;
- short refNum;
- Handle h, textHandle;
-
- GetAppParms(appName, &refNum, &h);
- PstringToText((char *)appName, &textHandle);
- tokenContents->descriptorType = typeChar;
- tokenContents->dataHandle = textHandle;
- } break;
-
-
- case pVersion:
- return AECreateDesc(cLongInteger, (Ptr)&versionCode, sizeof(long), tokenContents);
- break;
-
- case pClipboard: {
- /* Return all of the items currently on the clipboard */
- /* The returned information is an AEList, and each data type */
- /* on the scrap gets its own entry in the list */
- /* Alas, since the OS doesn't supply the tools for getting all */
- /* of the types in the scrap, we have to scan the scrap ourselves... */
- char *scrapPtr, *scrapEnd;
- PScrapStuff scrapInfo;
- long scrapSize;
- OSType itemType;
- long itemLength;
- long index;
-
- err = AECreateList(NULL, 0, false, tokenContents);
- if (err != noErr) break;
-
- err = LoadScrap(); /* Make sure the scrap is in memory */
- if (err != noErr) break;
-
- scrapInfo = InfoScrap(); /* Get the base address of the scrap in RAM */
- MoveHHi(scrapInfo->scrapHandle);
- HLock (scrapInfo->scrapHandle);/* ...and lock it */
- scrapPtr = (char *)*scrapInfo->scrapHandle;
- scrapEnd = scrapPtr + scrapInfo->scrapSize;
-
- /* Now, we can proceed to scan the scrap in memory and extract each type */
- index = 1;
- while (scrapPtr < scrapEnd) {
- itemType = *(OSType *)scrapPtr;
- scrapPtr += sizeof(itemType);
- itemLength = *(long *)scrapPtr;
- scrapPtr += sizeof(itemLength);
- /* Move this information into the next entry on the list */
- err = AEPutPtr(tokenContents, index, itemType, scrapPtr, itemLength);
- if (err != noErr) return err;
- index++;
- /* Bump the pointer to the start of the next item */
- if (itemLength & 1) itemLength++; /* If it's odd, make it even */
- scrapPtr += itemLength;
- }
- HUnlock (scrapInfo->scrapHandle);
- } break;
- }
- }
- else
- /* We should return an ospec for the application here */
- err = errAENoSuchObject;
-
- return err;
- } /* App_ReadTokenData */
-
-
- OSErr App_WriteTokenData(const AEDesc *theToken, const AEDesc *data)
- {
- OSErr err = noErr;
- long numItems, index;
- AEDesc currItemDesc = {'null', NULL};
- AEKeyword theAEKeyword;
-
- if ((tokenFlags(*theToken) & kPropToken) && (tokenPropCode(*theToken) == pClipboard)) {
- /* Only the clipboard property is writable */
-
- /* The data should be an AE list containing a series of things to be placed on the */
- /* clipboard. The data type of each item is also the clipboard type for that data */
- /* Note that App_SetData has extracted the information as a list for us */
- err = ZeroScrap();
- if (err != noErr) return err;
-
- (void)AECountItems(data, &numItems);
- for (index = 1; index <= numItems; index++) {
- /* Copy each item onto the clipboard */
- err = AEGetNthDesc(data, index, typeWildCard, &theAEKeyword, &currItemDesc);
- if (err != noErr) {
- if (currItemDesc.dataHandle != NULL) AEDisposeDesc(&currItemDesc);
- return err;
- }
- HLock(currItemDesc.dataHandle);
- err = PutScrap(GetHandleSize(currItemDesc.dataHandle), currItemDesc.descriptorType,
- *currItemDesc.dataHandle);
- AEDisposeDesc(&currItemDesc);
- currItemDesc.dataHandle = NULL;
- }
- }
- else
- err = errAENotModifiable;
-
- return err;
- } /* App_WriteTokenData */
-
-
- /* Individual event handlers */
- OSErr App_GetData(AppleEvent *message, AppleEvent *reply, long refcon,
- AEDesc *token, AEDesc *replyObject)
- {
- return App_ReadTokenData(token, replyObject);
- } /* App_GetData */
-
-
- OSErr App_SetData(AppleEvent *message, AppleEvent *reply, long refcon,
- AEDesc *token, AEDesc *replyObject)
- {
- AEDesc theData;
- OSErr err;
-
- /* Since only the "pClipboard" property is writable, and the data for that is */
- /* supposed to be in a list, we'll extract the data as a list */
- err = AEGetKeyDesc(message, keyAEData, typeAEList, &theData);
- if (err == noErr) {
- err = App_WriteTokenData(token, &theData);
- (void)AEDisposeDesc(&theData);
- }
- return err;
- } /* App_SetData */
-
-
- /* Object command dispatcher */
-
- OSErr App_AE_Dispatcher(const AppleEvent *message, AppleEvent *reply, long refCon,
- AEEventClass classID, AEEventID eventID,
- const AEDesc *ospec, const AEDesc *token)
- {
- OSErr err = noErr;
- AEDesc replyDesc = {'null', 0L};
-
- if (classID == kAECoreSuite) {
- switch (eventID) {
-
- /* This code is assuming that the object specifier resolves to a single item. */
- /* This isn't always true… */
- case kAEGetData:
- err = App_GetData(message, reply, refCon, token, &replyDesc);
- break;
-
- case kAEGetDataSize: {
- /* We'll do this one by executing "Get Data" and then returning the */
- /* size of the information. This is not necesarily the most efficient */
- /* way to do things if your returned data is large. */
-
- AEDesc tempDesc = {'null', NULL};
- long dataSize;
-
- err = App_GetData(message, reply, refCon, token, &tempDesc);
- if (tempDesc.dataHandle != NULL) {
- dataSize = GetHandleSize(tempDesc.dataHandle);
- (void)AECreateDesc(typeLongInteger, (Ptr)&dataSize, sizeof(dataSize), &replyDesc);
- (void)AEDisposeDesc(&tempDesc);
- }
- }
- break;
-
- case kAESetData:
- err = App_SetData(message, reply, refCon, token, &replyDesc);
- break;
-
- /* Events which we don't handle */
- case kAEClone:
- case kAEClose:
- case kAECountElements:
- case kAECreateElement: /* Handled by the element itself */
- case kAEDelete:
- case kAEDoObjectsExist:
- case kAEGetClassInfo:
- case kAEMove:
- case kAEOpen:
- default:
- err = errAEEventNotHandled ;
- }
- }
- else
- err = errAEEventNotHandled;
-
- /* See if we need to return anything */
- if ((err == noErr) && (replyDesc.descriptorType != 'null')
- && (reply->descriptorType != 'null')) { /* Note: if the other side didn't ask for a reply, this could be a null desc */
- /* This code should be modified to handle lists */
- err = AEPutParamDesc(reply, keyDirectObject, &replyDesc);
- (void)AEDisposeDesc(&replyDesc);
- }
-
- return err;
- } /* App_Dispatcher */
-